JWT Authentication ব্যবহারের সময়, সাধারণত Access Token এর মেয়াদ শেষ হয়ে গেলে নতুন Access Token প্রাপ্ত করার জন্য একটি Refresh Token ব্যবহার করা হয়। Refresh Token দিয়ে একটি নতুন Access Token তৈরি করা যায়, যাতে ব্যবহারকারীর পুনরায় লগইন করার প্রয়োজন না হয়। এই প্রক্রিয়াটি Stateless Authentication এর সুবিধা বজায় রেখে নিরাপদে সেশন পরিচালনা করতে সাহায্য করে।
নিম্নে, Spring Security তে JWT Refresh Token কনফিগার করার জন্য ধাপে ধাপে নির্দেশনা দেওয়া হলো।
Step 1: JWT Token Generator তৈরি করুন
JWT Utility ক্লাস তৈরি করুন যা Access Token এবং Refresh Token উভয়ই জেনারেট করবে।
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import io.jsonwebtoken.Claims;
import java.util.Date;
public class JwtUtil {
private static final String SECRET_KEY = "secretKey"; // নিরাপদ রাখতে এই কীটি ভালোভাবে কনফিগার করতে হবে
// Access Token জেনারেট করা
public static String generateAccessToken(String username) {
return Jwts.builder()
.setSubject(username)
.setIssuedAt(new Date())
.setExpiration(new Date(System.currentTimeMillis() + 1000 * 60 * 15)) // 15 মিনিট
.signWith(SignatureAlgorithm.HS256, SECRET_KEY)
.compact();
}
// Refresh Token জেনারেট করা
public static String generateRefreshToken(String username) {
return Jwts.builder()
.setSubject(username)
.setIssuedAt(new Date())
.setExpiration(new Date(System.currentTimeMillis() + 1000 * 60 * 60 * 24)) // 24 ঘন্টা
.signWith(SignatureAlgorithm.HS256, SECRET_KEY)
.compact();
}
// টোকেনের মধ্যে তথ্য বের করা
public static Claims extractClaims(String token) {
return Jwts.parser()
.setSigningKey(SECRET_KEY)
.parseClaimsJws(token)
.getBody();
}
// টোকেনের ভ্যালিডিটি চেক করা
public static boolean isTokenExpired(String token) {
Date expiration = extractClaims(token).getExpiration();
return expiration.before(new Date());
}
// টোকেন থেকে ইউজার নাম বের করা
public static String extractUsername(String token) {
return extractClaims(token).getSubject();
}
// টোকেন ভ্যালিডেশন
public static boolean validateToken(String token, String username) {
return (username.equals(extractUsername(token)) && !isTokenExpired(token));
}
}
Step 2: JWT Refresh Token API তৈরি করুন
LoginController: Refresh Token API তৈরি করুন
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/auth")
public class AuthController {
@Autowired
private JwtUtil jwtUtil;
@PostMapping("/login")
public String login(@RequestParam String username, @RequestParam String password) {
// এখানে ইউজারনেম এবং পাসওয়ার্ড চেক করতে হবে (ধরি, সফল লগইন)
String accessToken = jwtUtil.generateAccessToken(username);
String refreshToken = jwtUtil.generateRefreshToken(username);
// ইউজারের জন্য access token এবং refresh token রিটার্ন করা
return "Access Token: " + accessToken + "\nRefresh Token: " + refreshToken;
}
@PostMapping("/refresh")
public String refreshToken(@RequestParam String refreshToken) {
if (jwtUtil.isTokenExpired(refreshToken)) {
return "Refresh Token expired!";
}
String username = jwtUtil.extractUsername(refreshToken);
String newAccessToken = jwtUtil.generateAccessToken(username);
return "New Access Token: " + newAccessToken;
}
}
/loginরিকোয়েস্টে ইউজারনেম এবং পাসওয়ার্ড দিয়ে সফল লগইন হলে, Access Token এবং Refresh Token তৈরি হবে।/refreshরিকোয়েস্টে Refresh Token পাঠালে, যদি Refresh Token বৈধ থাকে, তবে নতুন Access Token জেনারেট হবে।
Step 3: Spring Security Configuration
Spring Security কনফিগারেশন তৈরি করতে হবে যাতে /login এবং /refresh এ অননুমোদিত অ্যাক্সেস বন্ধ করা যায়।
SecurityConfig:
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
.authorizeRequests()
.antMatchers("/auth/login", "/auth/refresh").permitAll() // Login এবং Refresh API কে খোলা রাখা
.anyRequest().authenticated() // অন্য সব রিকোয়েস্টের জন্য Authentication প্রয়োজন
.and()
.formLogin().disable(); // ডিফল্ট লগইন ফর্ম নিষ্ক্রিয় করা
}
}
Step 4: JWT Filter (Optional)
আপনি যদি JWT ব্যবহার করে API গুলোতে সিকিউরিটি পরিচালনা করতে চান, তবে একটি JWT Filter যুক্ত করতে পারেন। এটি নিশ্চিত করবে যে প্রতিটি API রিকোয়েস্টে Authorization হেডারে JWT পাঠানো হচ্ছে এবং সেটি ভ্যালিড কিনা চেক করবে।
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.filter.OncePerRequestFilter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class JwtFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
String authorizationHeader = request.getHeader("Authorization");
if (authorizationHeader != null && authorizationHeader.startsWith("Bearer ")) {
String token = authorizationHeader.substring(7);
String username = JwtUtil.extractUsername(token);
if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) {
if (JwtUtil.validateToken(token, username)) {
// Add authentication object to context
SecurityContextHolder.getContext().setAuthentication(new UsernamePasswordAuthenticationToken(username, null, new ArrayList<>()));
}
}
}
filterChain.doFilter(request, response);
}
}
Step 5: Filter Config (JWT Filter যোগ করা)
@Configuration
public class FilterConfig {
@Bean
public FilterRegistrationBean<JwtFilter> jwtFilter() {
FilterRegistrationBean<JwtFilter> registrationBean = new FilterRegistrationBean<>();
registrationBean.setFilter(new JwtFilter());
registrationBean.addUrlPatterns("/api/*"); // সমস্ত API রিকোয়েস্টে ফিল্টার কার্যকর হবে
return registrationBean;
}
}
Step 6: টেস্ট করুন
- Login রিকোয়েস্ট:
- URL:
POST http://localhost:8080/auth/login?username=user&password=pass - রেসপন্সে Access Token এবং Refresh Token পাবেন।
- URL:
- Refresh Token রিকোয়েস্ট:
- URL:
POST http://localhost:8080/auth/refresh?refreshToken=<Refresh_Token> - রেসপন্সে New Access Token পাবেন।
- URL:
উপসংহার:
Spring Security তে JWT Refresh Token কনফিগার করা একটি কার্যকরী সমাধান যেটি ব্যবহারকারীর সেশন ম্যানেজমেন্ট এবং অ্যাপ্লিকেশনের নিরাপত্তা উন্নত করতে সাহায্য করে। Access Token এর মেয়াদ শেষ হয়ে গেলে Refresh Token এর মাধ্যমে সহজেই নতুন Access Token তৈরি করা যায়, যাতে ব্যবহারকারীকে পুনরায় লগইন করতে না হয়।
Read more